<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>听力文件系统</title>
    <link rel="stylesheet" href="lib/element-ui.css">
    <link rel="stylesheet" href="css/index.css">
    <style>
        /* 为播放器弹窗增加一些特定样式 */
        .audio-player-modal .el-dialog__header {
            border-bottom: 1px solid #ebeef5;
        }
        .audio-player-modal .el-dialog__body {
            padding: 20px 30px 30px;
        }
        .player-title {
            font-size: 22px;
            font-weight: 600;
            color: #303133;
            margin-bottom: 8px;
            text-align: center;
        }
        .player-description {
            font-size: 14px;
            color: #909399;
            margin-bottom: 25px;
            text-align: center;
        }
        .player-progress-bar {
            display: flex;
            align-items: center;
            margin-bottom: 15px;
        }
        .player-time {
            font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
            font-size: 14px;
            color: #606266;
            width: 60px;
        }
        .player-time.left { text-align: right; margin-right: 15px; }
        .player-time.right { text-align: left; margin-left: 15px; }

        .player-main-controls {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 20px;
        }
        .play-pause-btn {
            font-size: 28px !important; /* 增大播放/暂停按钮 */
        }
        .control-btn {
            font-size: 22px !important;
        }
        .player-extra-controls {
            display: flex;
            justify-content: center; /* 将倍速也居中 */
            align-items: center;
            margin-top: 25px;
        }
    </style>
</head>

<body>
<div id="app">
    <el-container style="height: 100vh;">
        <!-- 顶部 Header -->
        <el-header class="app-header">
            <div class="header-title">{{ siteTitle }}</div>
            <div class="search-bar">
                <el-input placeholder="请输入关键词搜索..." v-model="searchKeyword" @keyup.enter.native="handleSearch"
                          clearable @clear="fetchAllAudioFiles">
                    <el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
                </el-input>
            </div>
        </el-header>

        <el-container>
            <!-- 侧边栏 Aside -->
            <el-aside width="280px" class="app-aside">
                <div class="category-title">分类筛选</div>
                <el-menu :default-active="selectedLevel1" @select="handleSelectLevel1">
                    <el-menu-item index="all">
                        <i class="el-icon-menu"></i>
                        <span slot="title">全部文件</span>
                    </el-menu-item>
                    <el-menu-item v-for="cat in level1List" :key="cat.categoryId" :index="String(cat.categoryId)">
                        <i class="el-icon-folder"></i>
                        <span slot="title">{{ cat.name }}</span>
                    </el-menu-item>
                </el-menu>

                <!-- 二级分类 -->
                <div v-if="selectedLevel1 !== 'all' && displayLevel2List.length > 0">
                    <div class="category-title" style="margin-top: 20px;">二级分类</div>
                    <el-menu :default-active="selectedLevel2" @select="handleSelectLevel2" class="level2-menu">
                        <el-menu-item index="all">
                            <i class="el-icon-document-copy"></i>
                            <span slot="title">全部</span>
                        </el-menu-item>
                        <el-menu-item v-for="subCat in displayLevel2List" :key="subCat.subcategoryId"
                                      :index="String(subCat.subcategoryId)">
                            <i class="el-icon-headset"></i>
                            <span slot="title">{{ subCat.subcategoryName }}</span>
                        </el-menu-item>
                    </el-menu>
                </div>
            </el-aside>

            <!-- 主内容区域 Main -->
            <el-main class="app-main">
                <el-row :gutter="20">
                    <template v-if="audioList.length > 0">
                        <el-col :xs="24" :sm="12" :md="8" :lg="8" v-for="audio in audioList" :key="audio.audioId">
                            <el-card class="audio-card">
                                <div slot="header" class="card-header">
                                    <span>{{ audio.title }}</span>
                                    <el-tag size="small">{{ audio.subcategoryName || '未分类' }}</el-tag>
                                </div>
                                <div class="card-description">{{ audio.description || '暂无描述' }}</div>
                                <!-- 卡片内只保留播放和下载按钮 -->
                                <div class="card-actions" style="margin-top: 15px; text-align: right;">
                                    <el-button type="primary" icon="el-icon-video-play" @click="openPlayer(audio)">播放</el-button>
                                    <el-button type="info" plain icon="el-icon-download" @click="handleDownload(audio.audioId)">下载</el-button>
                                </div>
                            </el-card>
                        </el-col>
                    </template>
                    <template v-else>
                        <el-col :span="24">
                            <div class="empty-state">
                                <el-empty description="暂无听力文件"></el-empty>
                            </div>
                        </el-col>
                    </template>
                </el-row>
            </el-main>
        </el-container>
    </el-container>

    <!-- 全局唯一的 audio 标签，由弹窗控制 -->
    <audio ref="audioPlayer"
           @timeupdate="updatePlayerProgress"
           @loadedmetadata="onPlayerLoadedMetadata"
           @ended="onPlayerEnded">
    </audio>

    <!-- 全新的音频播放器弹窗 -->
    <el-dialog
            :visible.sync="playerVisible"
            width="600px"
            :close-on-click-modal="false"
            @close="closePlayer"
            custom-class="audio-player-modal"
            :show-close="true"
            title="音频播放器">

        <h2 class="player-title">{{ playerData.title }}</h2>
        <p class="player-description">{{ playerData.description }}</p>

        <!-- 进度条 -->
        <div class="player-progress-bar">
            <span class="player-time left">{{ formatTime(playerState.progress) }}</span>
            <el-slider
                    v-model="playerState.progress"
                    :max="playerState.duration"
                    :format-tooltip="formatTime"
                    @change="seekAudio"
                    :disabled="!playerState.duration > 0">
            </el-slider>
            <span class="player-time right">{{ formatTime(playerState.duration) }}</span>
        </div>

        <!-- 主要控制按钮 -->
        <div class="player-main-controls">
            <el-button class="control-btn" type="primary" plain circle icon="el-icon-refresh-left" @click="handleReplay" title="从头播放"></el-button>
            <el-button class="control-btn" type="primary" plain circle icon="el-icon-d-arrow-left" @click="handleRewind" title="快退10秒"></el-button>
            <el-button class="play-pause-btn" type="primary" circle :icon="playerState.isPlaying ? 'el-icon-video-pause' : 'el-icon-video-play'" @click="handlePlayPause"></el-button>
            <el-button class="control-btn" type="primary" plain circle icon="el-icon-d-arrow-right" @click="handleForward" title="快进10秒"></el-button>
        </div>

        <!-- 额外控制：倍速 -->
        <div class="player-extra-controls">
            <el-dropdown @command="handleSpeedChange">
                <el-button type="primary" plain>
                    倍速: x{{ playerState.speed.toFixed(1) }} <i class="el-icon-arrow-down el-icon--right"></i>
                </el-button>
                <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item command="0.5">x0.5</el-dropdown-item>
                    <el-dropdown-item command="1.0">x1.0</el-dropdown-item>
                    <el-dropdown-item command="1.5">x1.5</el-dropdown-item>
                    <el-dropdown-item command="2.0">x2.0</el-dropdown-item>
                </el-dropdown-menu>
            </el-dropdown>
        </div>
    </el-dialog>
</div>

<script src="lib/vue.js"></script>
<script src="lib/element-ui.js"></script>
<script src="lib/axios.js"></script>
<script src="js/api.js"></script>
<script>
    new Vue({
        el: '#app',
        data() {
            return {
                siteTitle: '听力文件系统',
                searchKeyword: '',
                level1List: [],
                allLevel2List: [],
                audioList: [],
                selectedLevel1: 'all',
                selectedLevel2: 'all',

                audioPlayer: null,

                // 播放器弹窗的独立状态
                playerVisible: false,
                playerData: {
                    audioId: null,
                    title: '加载中...',
                    description: '',
                    src: ''
                },
                playerState: {
                    isPlaying: false,
                    progress: 0,
                    duration: 0,
                    speed: 1.0,
                }
            };
        },
        computed: {
            displayLevel2List() {
                if (this.selectedLevel1 === 'all') {
                    return [];
                }
                const categoryId = parseInt(this.selectedLevel1, 10);
                return this.allLevel2List.filter(item => item.categoryId === categoryId);
            }
        },
        async mounted() {
            this.audioPlayer = this.$refs.audioPlayer;
            this.$message({
                message: '正在加载数据...',
                type: 'info',
                duration: 1500
            });
            await Promise.all([
                this.fetchSiteTitle(),
                this.fetchLevel1Categories(),
                this.fetchLevel2Categories(),
                this.fetchAllAudioFiles()
            ]);
        },
        methods: {
            // --- 数据获取 ---
            async fetchSiteTitle() {
                try {
                    const res = await sysApi.getTitle();
                    if (res.data) {
                        this.siteTitle = res.data;
                        document.title = res.data;
                    }
                } catch (error) {
                    console.error("获取网站标题失败:", error);
                }
            },
            async fetchLevel1Categories() {
                try {
                    const res = await categoryApi.level1.list();
                    this.level1List = res.data || [];
                } catch (error) {
                    this.$message.error('获取一级分类失败: ' + error.message);
                }
            },
            async fetchLevel2Categories() {
                try {
                    const res = await categoryApi.level2.list();
                    this.allLevel2List = res.data || [];
                } catch (error) {
                    this.$message.error('获取二级分类失败: ' + error.message);
                }
            },
            async fetchAllAudioFiles() {
                try {
                    const res = await audioApi.list();
                    this.audioList = res.data || [];
                } catch (error) {
                    this.$message.error('获取听力文件列表失败: ' + error.message);
                }
            },

            // --- 筛选和搜索 ---
            async handleSelectLevel1(level1Id) {
                this.selectedLevel1 = level1Id;
                this.selectedLevel2 = 'all';
                this.searchKeyword = '';

                if (level1Id === 'all') {
                    await this.fetchAllAudioFiles();
                } else {
                    try {
                        const params = { level1CategoryId: parseInt(level1Id, 10) };
                        const res = await audioApi.listByCategory(params);
                        this.audioList = res.data || [];
                    } catch (error) {
                        this.$message.error('按分类获取文件失败: ' + error.message);
                    }
                }
            },
            async handleSelectLevel2(level2Id) {
                this.selectedLevel2 = level2Id;
                this.searchKeyword = '';

                try {
                    let params = {};
                    if (level2Id === 'all') {
                        params = { level1CategoryId: parseInt(this.selectedLevel1, 10) };
                    } else {
                        params = { level2CategoryId: parseInt(level2Id, 10) };
                    }
                    const res = await audioApi.listByCategory(params);
                    this.audioList = res.data || [];
                } catch (error) {
                    this.$message.error('按分类获取文件失败: ' + error.message);
                }
            },
            async handleSearch() {
                if (!this.searchKeyword.trim()) {
                    this.$message.warning('请输入搜索关键词');
                    return;
                }
                try {
                    const res = await audioApi.search(this.searchKeyword.trim());
                    this.audioList = res.data || [];
                    this.selectedLevel1 = 'all';
                    this.selectedLevel2 = 'all';
                    this.$message.success('搜索完成');
                } catch (error) {
                    this.$message.error('搜索失败: ' + error.message);
                }
            },

            // --- 下载 ---
            async handleDownload(audioId) {
                try {
                    const res = await audioApi.download(audioId);
                    if (res.data) {
                        const link = document.createElement('a');
                        link.href = res.data;
                        link.download = res.data.split('/').pop();
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                        this.$message.success('已开始下载');
                    }
                } catch(error) {
                    this.$message.error('下载失败: ' + error.message);
                }
            },

            // --- 辅助函数 ---
            formatTime(seconds) {
                if (isNaN(seconds) || seconds < 0) return '00:00';
                const min = Math.floor(seconds / 60);
                const sec = Math.floor(seconds % 60);
                return `${min < 10 ? '0' : ''}${min}:${sec < 10 ? '0' : ''}${sec}`;
            },

            // --- 全新的播放器控制逻辑 ---
            async openPlayer(audio) {
                try {
                    // 如果当前有音频正在播放，先关闭
                    if (this.playerVisible) {
                        this.closePlayer();
                    }

                    this.$message.info('正在获取音频资源...');
                    const res = await audioApi.play(audio.audioId);
                    if (res.data) {
                        this.playerData = { ...audio, src: res.data };
                        this.audioPlayer.src = res.data;
                        this.playerVisible = true;
                        // 使用.then确保DOM更新后再播放
                        this.$nextTick(() => {
                            this.audioPlayer.play().catch(error => {
                                console.error("自动播放失败:", error);
                                // 某些浏览器禁止自动播放，需要用户交互
                                this.playerState.isPlaying = false;
                            });
                        });
                    }
                } catch (error) {
                    this.$message.error('播放失败: ' + error.message);
                }
            },

            closePlayer() {
                this.audioPlayer.pause();
                this.playerData = { audioId: null, title: '', description: '', src: '' };
                this.playerState = { isPlaying: false, progress: 0, duration: 0, speed: 1.0 };
                this.playerVisible = false;
            },

            // 播放器事件监听
            onPlayerLoadedMetadata() {
                this.playerState.duration = this.audioPlayer.duration;
                this.playerState.isPlaying = !this.audioPlayer.paused;
                this.audioPlayer.playbackRate = this.playerState.speed;
            },
            updatePlayerProgress() {
                this.playerState.progress = this.audioPlayer.currentTime;
                // 解决暂停时状态可能不同步的问题
                if (this.audioPlayer.paused !== !this.playerState.isPlaying) {
                    this.playerState.isPlaying = !this.audioPlayer.paused;
                }
            },
            onPlayerEnded() {
                this.playerState.isPlaying = false;
                // 播放结束，进度条到头，但按钮变回播放状态
                this.playerState.progress = this.playerState.duration;
            },

            // 播放器控制方法
            handlePlayPause() {
                if (this.playerState.isPlaying) {
                    this.audioPlayer.pause();
                } else {
                    // 如果播放结束了，先回到开头再播放
                    if (this.playerState.progress >= this.playerState.duration) {
                        this.audioPlayer.currentTime = 0;
                    }
                    this.audioPlayer.play();
                }
            },
            handleRewind() {
                if (!this.playerState.duration) return;
                this.audioPlayer.currentTime = Math.max(0, this.audioPlayer.currentTime - 10);
            },
            handleForward() {
                if (!this.playerState.duration) return;
                this.audioPlayer.currentTime = Math.min(this.playerState.duration, this.audioPlayer.currentTime + 10);
            },
            handleReplay() {
                if (!this.playerState.duration) return;
                this.audioPlayer.currentTime = 0;
                this.audioPlayer.play();
            },
            seekAudio(value) {
                if (!this.playerState.duration) return;
                this.audioPlayer.currentTime = value;
            },
            handleSpeedChange(command) {
                const speed = parseFloat(command);
                this.playerState.speed = speed;
                this.audioPlayer.playbackRate = speed;
            }
        }
    });
</script>
</body>
</html>